import 'dart:io';

import 'package:dio/dio.dart';
import 'dart:convert';
import 'package:flutter_juwo/ui/GlobalConfig.dart';
import 'package:flutter_juwo/ui/res/shared_preferences_keys.dart';
import 'package:flutter_juwo/ui/utils/sp_util.dart';

import 'ResultCode.dart';
import 'api.dart';

/*
 * 网络请求管理类
 * token
 */
class DioManager {
  //单例
  static DioManager _instance;

  static DioManager getInstance() {
    if (_instance == null) {
      _instance = DioManager();
    }
    return _instance;
  }

  Dio dio = new Dio();

  DioManager() {
    // Set default configs
    dio.options.contentType =
        ContentType.parse("application/x-www-form-urlencoded");

    dio.options.baseUrl = Api.baseUrl;
    dio.options.connectTimeout = 12000;
    dio.options.receiveTimeout = 12000;
    dio.options.headers = {
      'Accept': 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      'Authorization': "**",
      'User-Aagent': "4.1.0;android;6.0.1;default;A001",
      "HZUID": "2",
    };

    dio.interceptors
        .add(LogInterceptor(responseBody: GlobalConfig.isDebug)); //是否开启请求日志
  }

  //get请求
  get(String url, FormData params, Function successCallBack,
      Function errorCallBack,
      {isToken = true}) async {
    isToken
        ? dio.options.headers
            .addAll({"token": SpUtil.getString(SpKeys.userToken)})
        : dio.options.headers.remove("token");
    _requstHttp(url, successCallBack, 'get', params, errorCallBack);
  }

  //post请求
  post(String url, params, Function successCallBack, Function errorCallBack,
      {isToken = true}) async {
    print("dio 属性 headers：${dio.options.headers.toString()}");
    isToken
        ? dio.options.headers
            .addAll({"token": SpUtil.getString(SpKeys.userToken)})
        : dio.options.headers.remove("token");

    _requstHttp(url, successCallBack, "post", params, errorCallBack);
  }

  _requstHttp(String url, Function successCallBack,
      [String method, FormData params, Function errorCallBack]) async {
    Response response;
    try {
      if (method == 'get') {
        if (params != null && params.isNotEmpty) {
          response = await dio.get(url, queryParameters: params);
        } else {
          response = await dio.get(url);
        }
      } else if (method == 'post') {
        if (params != null && params.isNotEmpty) {
          response = await dio.post(url, data: params);
        } else {
          response = await dio.post(url);
        }
      }
    } on DioError catch (error) {
      // 请求错误处理
      Response errorResponse;
      if (error.response != null) {
        errorResponse = error.response;
      } else {
        errorResponse = new Response(statusCode: 666);
      }
      // 请求超时
      if (error.type == DioErrorType.CONNECT_TIMEOUT) {
        errorResponse.statusCode = ResultCode.CONNECT_TIMEOUT;
      }
      // 一般服务器错误
      else if (error.type == DioErrorType.RECEIVE_TIMEOUT) {
        errorResponse.statusCode = ResultCode.RECEIVE_TIMEOUT;
      }

      // debug模式才打印
      if (GlobalConfig.isDebug) {
        print('请求异常: ' + error.toString());
        print('请求异常url: ' + url);
        print('请求头: ' + dio.options.headers.toString());
        print('method: ' + method);
      }
      _error(errorCallBack, error.message);
      return '';
    }
    // debug模式打印相关数据
    if (GlobalConfig.isDebug) {
      print('请求url: ' + url);
      print('请求头: ' + dio.options.headers.toString());
      if (params != null) {
        print('请求参数: ' + params.toString());
      }
      if (response != null) {
        print('返回参数: ' + response.toString());
      }
    }
    // var dataStr = json.encode(response.data);
    var dataMap = json.decode(response.data);

    successCallBack(dataMap);
  }

  _error(Function errorCallBack, String error) {
    if (errorCallBack == null) {
      errorCallBack(Api.ERR_UNKNOW);
    } else if (error.startsWith("Receiving data timeout")||error.contains("DioErrorType.CONNECT_TIMEOUT")) {
      ///请求超时
      errorCallBack(Api.ERR_TIME_OUT);
    } else if (error.contains("SocketException: Connection failed")) {
      ///无法连接服务器--
      errorCallBack(Api.ERR_CONNECTION_FAILED);
      return;
    } else if (error.contains("Http status error [401]")) {
      ///无法连接服务器
      errorCallBack(Api.ERR_401);
      return;
    } else {
      errorCallBack(Api.ERR_DATA);
    }
  }
}
